package com.spring.demo1;

import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.*;

/**
 * 获取注解的测试
 *
 * @author vhans
 */
public class AnnotatedElementTest {
    @Test
    public void AnnTest() {
        // 获取AnnTest类上的注解
        for (Annotation annotation : AnnTest.class.getAnnotations()) {
            System.out.println(annotation);
        }
    }

    @Test
    public void AnnTypeTest() {
        // 解析类后面的尖括号中的注解
        // 先获取类型变量信息
        TypeVariable<Class<AnnTypeTest>>[] typeVariables = AnnTypeTest.class.getTypeParameters();
        for (TypeVariable<Class<AnnTypeTest>> typeVariable : typeVariables) {
            System.out.println(typeVariable.getName() + "变量类型注解信息:");
            // 再获取注解变量上的注解信息
            Annotation[] annotations = typeVariable.getAnnotations();
            for (Annotation annotation : annotations) {
                System.out.println(annotation);
            }
        }
    }

    @Test
    public void AnnTestField() throws NoSuchFieldException {
        // 解析字段name上的注解信息
        Field name = AnnTest.class.getDeclaredField("name");
        for (Annotation annotation : name.getAnnotations()) {
            System.out.println(annotation);
        }
    }

    @Test
    public void AnnUseTestMap() throws NoSuchFieldException {
        // 解析map中泛型变量类型的注解信息
        // 获取map字段
        Field map = AnnUseTest.class.getDeclaredField("map");
        // 获取<T,V>泛型类型
        Type genericType = map.getGenericType();
        // 获取T,V泛型变量类型
        Type[] names = ((ParameterizedType) genericType).getActualTypeArguments();

        // 获取<T,V>中的注解信息
        AnnotatedType annotatedType = map.getAnnotatedType();
        // 获取T,V的注解信息
        AnnotatedType[] annotatedActualTypeArguments = ((AnnotatedParameterizedType) annotatedType).getAnnotatedActualTypeArguments();
        int i = 0;
        for (AnnotatedType actualTypeArgument : annotatedActualTypeArguments) {
            Type name = names[i++];
            System.out.println(name.getTypeName() + "类型上的注解如下:");
            for (Annotation annotation : actualTypeArgument.getAnnotations()) {
                System.out.println(annotation);
            }
        }
    }

    @Test
    public void AnnTestConstructor() {
        // 获取构造器上的注解信息
        Constructor<?> constructor = AnnTest.class.getConstructors()[0];
        for (Annotation annotation : constructor.getAnnotations()) {
            System.out.println(annotation);
        }
    }

    @Test
    public void AnnTestFun() throws NoSuchMethodException {
        // 获取方法上的注解信息
        Method fun = AnnTest.class.getMethod("fun", String.class, int.class);
        for (Annotation annotation : fun.getAnnotations()) {
            System.out.println(annotation);
        }
    }

    @Test
    public void AnnTestFunField() throws NoSuchMethodException {
        // 获取方法的参数上的注解信息
        Method fun = AnnTest.class.getMethod("fun", String.class, int.class);
        for (Parameter parameter : fun.getParameters()) {
            System.out.printf("参数%s上的注解如下:%n", parameter.getName());
            for (Annotation annotation : parameter.getAnnotations()) {
                System.out.println(annotation);
            }
        }
    }
}
